<?php
require_once 'Xiachufang/entity/Actor.php';
class ActorLogic {
 	const ACTOR_COOKIE_NAME = "x_a";
    private $maskData = "com_deng_xia0*fang_$#";
    private $log;

    function __construct() {
		$this->log = Logger::getLogger("XiachufangCookie");
    }
    
	static function getPasswordMd5($password) {
		return md5("d$@d_".$password."_xiachufang_");
	}
	/**
	 * 检查是否存在指定的email
	 *
	 * @param unknown_type $email
	 * @return unknown
	 */
	static function exist($email) {
		$table = ActorEntity::getTable();
		$sql = "select count(*) from ".$table." where email=?";
		$db = DBMgr::getSlaver($table);
		$num = $db->querySingle($sql, array($email));
		return $num > 0;
	}
	
	/**
	 * 登陆用户
	 *
	 * @param unknown_type $email
	 * @param unknown_type $password
	 * @return ActorEntity 没有找到则返回false。否则返回用户的status值
	 */
	static function login($email, $password, $persist=false,$useMainDomain=true) {
		$password = self::getPasswordMd5($password);
		$table = ActorEntity::getTable();
		$sql = "select * from ".$table." where email=? and password=?";
		$db = DBMgr::getSlaver($table);
		$data = $db->queryUnique($sql, array($email, $password));
		if ($data == NULL) {
			return false;
		}
		$actor = new ActorEntity();
		$actor->installData($data);
		if ($actor->status == 0) return 0;
		
		$logic = new ActorLogic();
		$logic->encodeActor($actor, $persist, $useMainDomain);
		return $actor->status;
	}
	
	/**
	 * 登出用户
	 *
	 */
	static function logout() {
		$actor = new ActorEntity();
		$logic = new ActorLogic();
		$logic->encodeActor($actor);
	}


	/**
	 * 发送邮箱验证码
	 *
	 * @param unknown_type $actorId
	 * @param unknown_type $email
	 * @param unknown_type $nickname
	 */
	static function sendEmailValidCode($actorId, $email, $nickname) {
		require 'Xiachufang/phpmailer/class.phpmailer.php';
		$mail = new phpmailer();
		$mail->IsSMTP();
		$mail->Host = "smtp.163.com";
		$mail->SMTPAuth = true;
		$mail->Username = "comdeng";
		$mail->Password = "wojiushiwo";
		$mail->From = "comdeng@163.com"; 
		$mail->FromName = "comdeng"; 
		$mail->AddAddress($email, $nickname);
		$mail->IsHTML(true);
		$mail->CharSet = "UTF-8";
		$mail->Subject = "xiachufang.com account validation";
		
		$validCode = rawurlencode(ActorLogic::getEmailValidCode($email, $actorId));
		$validUrl = "http://xiachufang.cn/action/email/validate?actorId=$actorId&validCode=$validCode";
		$sendDate = strftime("%y-%m-%d");
		$mail->Body = <<<BODY
<h2>$nickname:</h2>
&nbsp;&nbsp;恭喜你注册成为<a href="http://www.xiachufang.com">下厨房</a>的用户。请点击下面的链接激活你的账户：<br/>
<p><a href="$validUrl">$validUrl</a></p>
<br/>
<br/>
下厨房<br/>
$sendDate
BODY;
		if ($mail->Send()) {
			Logger::getLogger("email")->info("mail to $email success.");
		} else {
			Logger::getLogger("email")->info("mail to $email failed.");
		}
	}
	
	/**
	 * 得到邮箱验证码
	 *
	 * @param unknown_type $email
	 * @param unknown_type $actorId
	 */
	static function getEmailValidCode($email, $actorId) {
		$al = new ActorLogic();
		return base64_encode($al->_mask($email."_".$actorId));
	}
	
	/**
	 * 验证邮箱验证码是否正确
	 *
	 * @param unknown_type $email
	 * @param unknown_type $actorId
	 * @param unknown_type $validCode
	 * @return unknown
	 */
	static function checkEmailValidCode($email, $actorId, $validCode) {
		$al = new ActorLogic();
		return $al->_unmask(base64_decode($validCode)) == $email."_".$actorId;
	}
	
    function _mask($data) {
        $maskDataMd5 = md5($this->maskData,true);
        $len = strlen($data);
        $result = '';
        for($i=0;$i<$len;) {
            for($j=0;$i<$len && $j<16;$i++,$j++) {
                $result .= $data[$i]^$maskDataMd5[$j];
            }
        }
        return $result;
    }

    function _unmask($data) {
        return $this->_mask($data);
    }

    /**
     * 根据cookie信息判断用户是否已登录.
     * @return bool true 已登录,false 未登录.
     */
    function isLogon($cookieValue=NULL) {
        $result = $this->getActorId($cookieValue);
        return $result!==false;
    }

    /**
     * 是否为匿名
     *
     * @param unknown_type $cookieValue
     * @return unknown
     */
    function isAnonymous($cookieValue=NULL) {
       $actorId = $this->getActorId($cookieValue);
       if ($actorId !== false){
       		$actorEntity = new ActorEntity();
       		if ($actorEntity->get($actorId) !== false){
       			return $actorEntity->isAnonymous();
       		}
       }
       return false;
    }
    function getActorCookie($name){
        return $_COOKIE[$name];
    }
//    /**
//     * 得到用户昵称
//     *
//     * @return unknown
//     */
//    function getActorName(){
//        return urldecode($this->getActorCookie('x_n')); 
//    }
    /**
     * 得到用户ID
     *
     * @param unknown_type $cookieValue
     * @return unknown
     */
    function getActorId($cookieValue=NULL) {
        if ($cookieValue==NULL) {
            if (isset($_COOKIE[self::ACTOR_COOKIE_NAME])) {
                $cookieValue = $_COOKIE[self::ACTOR_COOKIE_NAME];
            }
            else {
                return false;
            }
        }
        $s = base64_decode($cookieValue);
        $s = $this->_unmask($s);
        $rpos = strrpos($s,"\n");
        if ($rpos===false) {
            return false;
        }
        $data = substr($s,0,$rpos+1);
        $sign = substr($s,$rpos+1);
        if (md5($data)!=$sign) {
            return false;
        }
        $nvs = explode("\n",$data);
        $result = array();
        foreach ($nvs as $nv) {
            if (preg_match("{^([^=]+)=(.*)$}",$nv,$capture)) {
                $result[$capture[1]] = $capture[2];
            }
        }
        if (!isset($result['actorId'])) {
            return false;
        }
//    	//防止非法修改cookie中的x_i
//    	if ($result['actorId'] != $_COOKIE["x_i"]){
//    		return false;
//    	}
        return $result['actorId'];
    }

    /**
     * Enter description here...
     *
     * @param unknown_type $cookieValue
     * @return ActorEntity
     */
    function decodeActor($cookieValue=NULL) {
        if ($cookieValue==NULL) {
            if (isset($_COOKIE[self::ACTOR_COOKIE_NAME])) {
                if ($this->log->isDebugEnabled()) {
                    $this->log->debug("cookievalue=".$cookieValue);
                }
                $cookieValue = $_COOKIE[self::ACTOR_COOKIE_NAME];
            }
            else {
                return false;
            }
        }
        $s = base64_decode($cookieValue);
        $s = $this->_unmask($s);
        $rpos = strrpos($s,"\n");
        if ($rpos===false) {
            return false;
        }
        $data = substr($s,0,$rpos+1);
        $sign = substr($s,$rpos+1);
        if (md5($data)!=$sign) {
            return false;
        }
        $nvs = explode("\n",$data);
        $result = array();
        foreach ($nvs as $nv) {
            if (preg_match("{^([^=]+)=(.*)$}",$nv,$capture)) {
                $result[$capture[1]] = $capture[2];
            }
        }
        if (!isset($result['actorId'])) {
            return false;
        }
        if (strlen($result['actorId']) >= 32){
        	return false;
        }
    	//防止非法修改cookie中的x_i
//    	if ($result['actorId'] != $_COOKIE["x_i"]){
//    		return false;
//    	}
    	if ((int)$result['actorId'] == 0){
    		return false;
    	}
        $actor = new ActorEntity();
        if ($actor->get($result["actorId"])) {
		   //超过12小时更新用户的最后登录时间
		   // TODO
		   return $actor;
        }
       	return false;
    }
    /**
     * Enter description here...
     *
     * @param ActorEntity $actor
     * @param unknown_type $persist
     * @param unknown_type $useMainDomain
     * @return unknown
     */
	function encodeActor(ActorEntity $actor,$persist=false,$useMainDomain=true) {
        $expire = time()-3600;
        $path = '/';
        $domain = $_SERVER['SERVER_NAME'];
		$utraDomain = $domain;//$_SERVER["HTTP_HOST"];
		$domains = explode(".",$utraDomain);
		
		if ($useMainDomain && count($domains) > 2 && preg_match('/\d+\.\d+\.\d+\.\d+/',$domain) == 0){
			$domains = array_slice($domains,count($domains)-2,2);
			$utraDomain = ".".implode(".",$domains);
		}
		
        if ($actor->actorId) { //添加新的cookie
	        $value = '';
	        if ($actor->actorId!==NULL) {
	            $s = '';
	            $s .= "actorId=".$actor->actorId."\n";
	            $sign = md5($s);
	            $s .= $sign;
	            $masked = $this->_mask($s);
	            $value = base64_encode($masked);
	        }
			$expire = NULL;
	        if ($persist && $persist !=='0' && $persist !=='false') {
	            $expire = time()+10*365*24*60*60;
	        }
			setcookie(self::ACTOR_COOKIE_NAME,$value,$expire,$path,$utraDomain);
			//setcookie("x_i",$actor->actorId,$expire,$path,$utraDomain);
	        //setcookie("x_n",rawurlencode($actor->nickname),$expire,$path,$utraDomain);
	        setcookie("x_p","$persist",$expire,$path,$utraDomain);
        } else {
        	setcookie(self::ACTOR_COOKIE_NAME,$value,$expire,$path,$utraDomain);
			//setcookie("x_i",$actor->actorId,$expire,$path,$utraDomain);
	        //setcookie("x_n",rawurlencode($actor->nickname),$expire,$path,$utraDomain);
	        setcookie("x_p","$persist",$expire,$path,$utraDomain);
        }
        return $value;
    }
}
?>